package com.hxzy.service.impl;

import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hxzy.common.enums.AckCode;
import com.hxzy.common.exception.ServiceException;
import com.hxzy.common.exception.ServiceStringException;
import com.hxzy.controller.seckill.req.SeckillReq;
import com.hxzy.entity.Orders;
import com.hxzy.entity.StoreCount;
import com.hxzy.entity.StoreCountVersion;
import com.hxzy.service.OrdersService;
import com.hxzy.service.StoreCountVersionService;
import com.hxzy.mapper.StoreCountVersionMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;

/**
* @author 11452
* @description 针对表【store_count_version(乐观锁)】的数据库操作Service实现
* @createDate 2023-09-11 16:35:44
*/
@Service
public class StoreCountVersionServiceImpl extends ServiceImpl<StoreCountVersionMapper, StoreCountVersion>
    implements StoreCountVersionService{

    @Autowired
    private OrdersService ordersService;

    /**
     * 数据库乐观锁的操作
     * @param req
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Long seckill(SeckillReq req) {
        //下订单
        Orders orders = new Orders();
        //使用数据库悲观锁 (如果操作比较耗时，其它线程等待时间就会比较久)
        StoreCountVersion db =super.getById(req.getStockId());
        if (db == null) {
            //抛出异常，事务回滚，查询锁取消
            throw new ServiceException(AckCode.NOT_FOUND_DATA);
        }
        if (db.getStore() < req.getCount()) {
            //抛出异常，事务回滚，查询锁取消
            throw new ServiceException(AckCode.SCKILL_NOT_NUM);
        }
        try{
            //这里要变化
            boolean result=this.updateSckillVersion(req,db);
            if(result) {
                //订单号
                orders.setOrderId(IdUtil.getSnowflakeNextId());
                orders.setUserId(req.getUserId());
                orders.setStockId(req.getStockId());
                orders.setNum(req.getCount());
                orders.setCreateTime(new Date());
                this.ordersService.save(orders);
            }else{
                //库存不足
                throw new ServiceException(AckCode.SCKILL_NOT_SUCCESS);
            }
        }catch (Exception e){
            //数据库操作失败
            throw new ServiceStringException(e.getMessage());
        }
        return orders.getOrderId();
    }


    /**
     * 乐观锁
     * @param req
     * @param db
     * @return
     */
    @Override
    public boolean updateSckillVersion(SeckillReq req, StoreCountVersion db) {
        return baseMapper.updateSckillVersion(req,db)>0;
    }
}




